﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace JNPF.Utils
{
    /// <summary>
    /// 动态Lamada
    /// 版 本：V3.0.0
    /// 版 权：引迈信息技术有限公司（https://www.jnpfsoft.com）
    /// 作 者：JNPF开发平台组
    /// </summary>
    public partial class ExtLinq<T> where T : new()
    {
        private List<Expression> m_lstExpression = null;
        private ParameterExpression m_Parameter = null;
        public ExtLinq()
        {
            m_lstExpression = new List<Expression>();
            m_Parameter = Expression.Parameter(typeof(T), "x");
        }
        public void CreateExpression(string strPropertyName, object strValue, SearchMethod expressType)
        {
            Expression expRes = null;
            MemberExpression member = Expression.PropertyOrField(m_Parameter, strPropertyName);
            if (expressType == SearchMethod.Contains)
            {
                expRes = Expression.Call(member, typeof(string).GetMethod("Contains"), Expression.Constant(strValue));
            }
            else if (expressType == SearchMethod.Equal)
            {
                expRes = Expression.Equal(member, Expression.Constant(strValue, member.Type));
            }
            else if (expressType == SearchMethod.NotEqual)
            {
                expRes = Expression.NotEqual(member, Expression.Constant(strValue, member.Type));
            }
            else if (expressType == SearchMethod.LessThan)
            {
                expRes = Expression.LessThan(member, Expression.Constant(strValue, member.Type));
            }
            else if (expressType == SearchMethod.LessThanOrEqual)
            {
                expRes = Expression.LessThanOrEqual(member, Expression.Constant(strValue, member.Type));
            }
            else if (expressType == SearchMethod.GreaterThan)
            {
                expRes = Expression.GreaterThan(member, Expression.Constant(strValue, member.Type));
            }
            else if (expressType == SearchMethod.GreaterThanOrEqual)
            {
                expRes = Expression.GreaterThanOrEqual(member, Expression.Constant(strValue, member.Type));
            }
            m_lstExpression.Add(expRes);
        }
        public void CreateExpression(string strPropertyName, List<object> lstValue)
        {
            Expression expRes = null;
            MemberExpression member = Expression.PropertyOrField(m_Parameter, strPropertyName);
            foreach (var oValue in lstValue)
            {
                if (expRes == null)
                {
                    expRes = Expression.Equal(member, Expression.Constant(oValue, member.Type));
                }
                else
                {
                    expRes = Expression.Or(expRes, Expression.Equal(member, Expression.Constant(oValue, member.Type)));
                }
            }
            m_lstExpression.Add(expRes);
        }
        public Expression<Func<T, bool>> GetLambda()
        {
            Expression whereExpr = null;
            foreach (var expr in this.m_lstExpression)
            {
                if (whereExpr == null)
                    whereExpr = expr;
                else
                    whereExpr = Expression.And(whereExpr, expr);
            }
            if (whereExpr == null)
                return null;
            return Expression.Lambda<Func<T, bool>>(whereExpr, m_Parameter);
        }
    }
    public enum SearchMethod
    {
        Contains,           //like
        Equal,              //等于
        NotEqual,           //不等于
        LessThan,           //小于
        LessThanOrEqual,    //小于等于
        GreaterThan,        //大于
        GreaterThanOrEqual  //大于等于
    }
}
